package com.abing.permissionsys.service.impl;


import com.abing.core.utils.BeanUtil;
import com.abing.permissionsys.entity.PageNavigation;
import com.abing.permissionsys.entity.PageResult;
import com.abing.permissionsys.entity.PageVal;
import com.abing.permissionsys.entity.domain.TimingJob;
import com.abing.permissionsys.entity.vo.TimingJobVO;
import com.abing.permissionsys.enums.TimingJobEnums;
import com.abing.permissionsys.mapper.TimingJobMapper;
import com.abing.permissionsys.service.TimingJobService;
import com.abing.permissionsys.timing.utils.ScheduleUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.List;


@Slf4j
@Service
public class TimingJobServiceImpl implements TimingJobService {
	@Autowired
	private TimingJobMapper timingJobMapper;
	@Autowired
	private ScheduleUtils scheduleUtils;
	@Override
	public PageResult list(TimingJobVO timingJobVO, PageVal pageVal) {
		QueryWrapper<TimingJob> queryWrapper=new QueryWrapper<TimingJob>();
		IPage<TimingJob> appDoList=timingJobMapper.selectPage(new PageNavigation<>(pageVal),queryWrapper);
		List<TimingJobVO> timingJobVOS= BeanUtil.doToVoList(appDoList.getRecords(),TimingJobVO.class);
		return new PageResult(appDoList,timingJobVOS);
	}

	@Override
	public int updateTime(TimingJobVO timingJobVO) {
		TimingJob timingJob=new TimingJob();
		timingJob.setPrevExecuteTime(timingJobVO.getPrevExecuteTime());
		timingJob.setNextExecuteTime(timingJobVO.getNextExecuteTime());
		timingJob.setId(timingJobVO.getId());
		return timingJobMapper.updateById(timingJob);
	}

	/**
	 * 项目启动时，初始化定时器
	 */
	@PostConstruct
	public void init(){
		List<TimingJob> timingJobList = timingJobMapper.selectList(null);
		log.info("timingJobList数量："+timingJobList.size()+"-----"+timingJobList);
		for(TimingJob timingJob : timingJobList){
			TimingJobVO timingJobVO=BeanUtil.voToDo(timingJob,TimingJobVO.class);
			CronTrigger cronTrigger = scheduleUtils.getCronTrigger(timingJobVO.getId());
			//如果不存在，则创建
			if(cronTrigger == null) {
				scheduleUtils.createScheduleJob(timingJobVO);
			}else {
				scheduleUtils.updateScheduleJob(timingJobVO);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int save(TimingJobVO timingJobVO){
		TimingJob timingJob=BeanUtil.voToDo(timingJobVO,TimingJob.class);
		int i=timingJobMapper.insert(timingJob);
		scheduleUtils.createScheduleJob(BeanUtil.voToDo(timingJob,TimingJobVO.class));
		return i;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int update(TimingJobVO timingJob){
		int i=timingJobMapper.updateById(BeanUtil.voToDo(timingJob,TimingJob.class));
		scheduleUtils.updateScheduleJob( timingJob);
		return i;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int remove(Long id){
		scheduleUtils.deleteScheduleJob(id);
		return timingJobMapper.deleteById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void run(Long id) {
		scheduleUtils.run(BeanUtil.doToVo(timingJobMapper.selectById(id),TimingJobVO.class));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void pause(Long id) {
		scheduleUtils.pauseJob( id);
		updateStateById(id,TimingJobEnums.StateEnum.PAUSE.getIndex());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void resume(Long id) {
		scheduleUtils.resumeJob(id);
		updateStateById(id,TimingJobEnums.StateEnum.NORMAL.getIndex());
	}

	/**
	 * 根据id更新状态
	 * @param id
	 * @return
	 */
	private int updateStateById(Long id,String state){
		TimingJob timingJob=new TimingJob();
		timingJob.setState(state);
		timingJob.setId(id);
		return timingJobMapper.updateById(timingJob);
	}
}
